using System;
using System.Collections.Generic;
using System.Linq;
using BCCommon.Enums;
using BCCommon.Enums.Chats;
using BCCommon.Extensions;
using BCEntity.Chats;
using BCDto.Chats.Thread;
using BCDto.Chats.Message;
using BCDto.Chats.User;

namespace BCService.Chats
{
    public static class ChatsExtension
    {
        private static readonly Dictionary<string, Type> CachedServices = new Dictionary<string, Type>(StringComparer.InvariantCultureIgnoreCase);

        static ChatsExtension()
        {
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (Type item in assembly.GetTypes())
                {
                    if (!(item.GetCustomAttributes(typeof(CustomerServiceAttribute), false).FirstOrDefault() is CustomerServiceAttribute attribute))
                    {
                        continue;
                    }

                    if (!item.GetInterfaces().Contains(typeof(ICustomerServiceService)))
                    {
                        continue;
                    }

                    CachedServices.Add(attribute.BusinessType, item);
                }
            }
        }

        /// <summary>
        /// 获取客服会话的业务实现。
        /// </summary>
        /// <param name="thread"></param>
        /// <param name="serviceProvider"></param>
        /// <returns></returns>
        internal static ICustomerServiceService GetService(this ThreadEntity thread, IServiceProvider serviceProvider)
        {
            if (thread == null)
            {
                throw new ArgumentNullException(nameof(thread));
            }

            if (thread.Type != ThreadType.CustomerService.ToString())
            {
                throw new ArgumentException("只有客服会话才可以执行此操作。");
            }

            return GetService(thread.BusinessType, serviceProvider);
        }

        internal static ICustomerServiceService GetService(this ThreadRequestDto requestDto, IServiceProvider serviceProvider)
        {
            if (requestDto == null)
            {
                throw new ArgumentNullException(nameof(requestDto));
            }

            if (requestDto.Type != ThreadType.CustomerService)
            {
                throw new ArgumentException("只有客服会话才可以执行此操作。");
            }

            return GetService(requestDto.BusinessType, serviceProvider);
        }

        private static ICustomerServiceService GetService(string businessType, IServiceProvider serviceProvider)
        {
            if (string.IsNullOrWhiteSpace(businessType))
            {
                return null;
            }

            if (!CachedServices.TryGetValue(businessType, out var serviceType))
            {
                return null;
            }

            var constructor = serviceType.GetConstructors().OrderByDescending(p => p.GetParameters().Length).First(); // 获取构造参数列表最多的构造方法
            var constructorParameters = constructor.GetParameters().Select(p => serviceProvider.GetService(p.ParameterType)); // 提取构造参数
            var service = Activator.CreateInstance(serviceType, constructorParameters.ToArray()); // 构建服务实例

            return service as ICustomerServiceService;
        }

        /// <summary>
        /// 将用户信息转换为参与人模型。
        /// </summary>
        /// <param name="user"></param>
        /// <param name="entity"></param>
        /// <returns></returns>
        internal static ThreadParticipantDto AsParticipantDto(this UserDto user, ThreadParticipantEntity entity)
        {
            return new ThreadParticipantDto
            {
                UserId = entity.ParticipantUserId,
                UserName = user.FullName,
                RoleType = user.RoleType,
                AliasName = entity.AliasName,
                AvatarUrl = user.AvatarUrl
            };
        }

        /// <summary>
        /// 获取聊天消息的预览文字。
        /// </summary>
        /// <param name="requestDto"></param>
        /// <returns></returns>
        public static string GetPreviewText(this MessageRequestDto requestDto)
        {
            if (requestDto.MessageType == MessageType.Sticker)
            {
                if (!string.IsNullOrWhiteSpace(requestDto.Content))
                {
                    return $"[{requestDto.Content}]";
                }
                else
                {
                    return $"[{requestDto.MessageType.GetDescriptionString()}]";
                }
            }

            if (requestDto.MessageType == MessageType.File)
            {
                if (requestDto.File.Type != BCCommon.Enums.Chats.FileType.Other)
                {
                    return $"[{requestDto.File.Type.GetDescriptionString()}] {requestDto.File.Name}";
                }
                else
                {
                    return $"[{requestDto.MessageType.GetDescriptionString()}] {requestDto.File.Name}";
                }
            }

            if (requestDto.MessageType == MessageType.Share)
            {
                return $"[{requestDto.MessageType.GetDescriptionString()}] {requestDto.Share.Title}";
            }

            if (requestDto.MessageType == MessageType.InfoCard)
            {
                return $"[{requestDto.MessageType.GetDescriptionString()}] {requestDto.InfoCard.Name}";
            }

            // 默认情况...
            if (!string.IsNullOrWhiteSpace(requestDto.Content))
            {
                return $"{requestDto.Content}";
            }
            else
            {
                return $"[{requestDto.MessageType.GetDescriptionString()}]";
            }
        }

        /// <summary>
        /// 获取适用于聊天的用户名。
        /// </summary>
        /// <param name="applicationContextService"></param>
        /// <returns></returns>
        public static string GetChatUserId(this IApplicationContextService applicationContextService)
        {
            if (applicationContextService.Anonymous != null)
            {
                return $"{RoleType.Anonymous.ToString().ToUpperInvariant()}-{applicationContextService.Anonymous.AnonymousId}";
            }

            if (applicationContextService.Admin != null)
            {
                return $"{RoleType.Admin.ToString().ToUpperInvariant()}-{applicationContextService.Admin.AdminId}";
            }

            if (applicationContextService.User != null)
            {
                return $"{applicationContextService.User.Role.ToString().ToUpperInvariant()}-{applicationContextService.User.UserId}";
            }

            throw new NotImplementedException();
        }

    }
}
